﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using YJKArch.Utils;

namespace YJKAreaCutter.Utils.InternalCorner
{
	public class InternalCornerManager
	{
		public static List<InternalCornerData> GetInternalCorner(List<Curve> lstConnectCurve)
		{
			List<InternalCornerData> list = new List<InternalCornerData>();
			List<XYZ> closedRegionPts = CurveUtils.GetClosedRegionPts(lstConnectCurve);
			int count = lstConnectCurve.Count;
			for (int i = 0; i < lstConnectCurve.Count; i++)
			{
				Curve curveF = lstConnectCurve[i];
				Curve curveS = lstConnectCurve[(i + 1) % count];
				InternalCornerData internalCornerData = InternalCornerManager.CreateInternalCorner(curveF, curveS, closedRegionPts, lstConnectCurve);
				if (internalCornerData != null)
				{
					list.Add(internalCornerData);
				}
			}
			return list;
		}

		public static List<Curve> GetRegionCornerExLine(List<Curve> lstConnectCurve)
		{
			new List<Curve>();
			List<InternalCornerData> internalCorner = InternalCornerManager.GetInternalCorner(lstConnectCurve);
			return InternalCornerManager.GetCornerMinExLine(lstConnectCurve, internalCorner);
		}

		private static InternalCornerData CreateInternalCorner(Curve curveF, Curve curveS, List<XYZ> lstClosedPt, List<Curve> lstClosedCurve)
		{
			InternalCornerData result = null;
			IntersectionResultArray intersectionResultArray = null;
			curveF.Intersect(curveS, out intersectionResultArray);
			if (intersectionResultArray == null || 1 != intersectionResultArray.Size)
			{
				return result;
			}
			IntersectionResult intersectionResult = intersectionResultArray.get_Item(0);
			if (intersectionResult == null)
			{
				return result;
			}
			XYZ xyzpoint = intersectionResult.XYZPoint;
			XYZ xyz = new XYZ(xyzpoint.X, xyzpoint.Y, 0.0);
			XYZ maxDistancePt = CurveUtils.GetMaxDistancePt(curveF, xyz);
			XYZ maxDistancePt2 = CurveUtils.GetMaxDistancePt(curveS, xyz);
			(maxDistancePt - maxDistancePt2).Normalize();
			XYZ vecF = maxDistancePt - xyz;
			XYZ vecS = maxDistancePt2 - xyz;
			if (Geometry.GetRotateAngle(vecF, vecS) < Math.PI)
			{
				result = new InternalCornerData(xyzpoint, curveF, curveS, lstClosedCurve);
			}
			return result;
		}

		public static List<Curve> GetCornerMinExLine(List<Curve> lstConnectCurve, List<InternalCornerData> lstCornerData)
		{
			List<Curve> list = new List<Curve>();
			foreach (InternalCornerData internalCornerData in lstCornerData)
			{
				XYZ intersectPt = internalCornerData.m_intersectPt;
				XYZ vecDir = -internalCornerData.m_vecMaxDirection;
				XYZ vecDir2 = -internalCornerData.m_vecMinDirection;
				Curve extensionLine = CurveUtils.GetExtensionLine(intersectPt, vecDir);
				Curve extensionLine2 = CurveUtils.GetExtensionLine(intersectPt, vecDir2);
				XYZ nearExtensionLineIntersectPt = CurveUtils.GetNearExtensionLineIntersectPt(internalCornerData, extensionLine, lstConnectCurve);
				XYZ nearExtensionLineIntersectPt2 = CurveUtils.GetNearExtensionLineIntersectPt(internalCornerData, extensionLine2, lstConnectCurve);
				Curve curve = null;
				if (nearExtensionLineIntersectPt != null && nearExtensionLineIntersectPt2 != null)
				{
					double num = intersectPt.DistanceTo(nearExtensionLineIntersectPt);
					double num2 = intersectPt.DistanceTo(nearExtensionLineIntersectPt2);
					if (num > num2)
					{
						curve = Line.CreateBound(intersectPt, nearExtensionLineIntersectPt2);
					}
					else
					{
						curve = Line.CreateBound(intersectPt, nearExtensionLineIntersectPt);
					}
				}
				else if (nearExtensionLineIntersectPt != null && nearExtensionLineIntersectPt2 == null)
				{
					curve = Line.CreateBound(intersectPt, nearExtensionLineIntersectPt);
				}
				else if (nearExtensionLineIntersectPt == null && nearExtensionLineIntersectPt2 != null)
				{
					curve = Line.CreateBound(intersectPt, nearExtensionLineIntersectPt2);
				}
				bool flag = true;
				foreach (Curve curve2 in lstConnectCurve)
				{
					IntersectionResultArray intersectionResultArray = null;
					SetComparisonResult setComparisonResult = curve2.Intersect(curve, out intersectionResultArray);
					if (intersectionResultArray != null && intersectionResultArray.Size > 1)
					{
						flag = false;
					}
					else if (setComparisonResult == SetComparisonResult.Equal)
					{
						flag = false;
					}
					if (!flag)
					{
						break;
					}
				}
				if (flag)
				{
					list.Add(curve);
				}
				if (list.Count > 0)
				{
					lstConnectCurve.AddRange(list);
				}
			}
			return list;
		}

		private static double m_dPointTrans = Common.MMtoIntch(0.1);
	}
}
